﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FrogEngine;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using SharedTypes;

namespace TestGame
{
	public class ShipModelEntity : ModelGameEntityBase//, IHandlesGamePadInput
	{
		public ShipModelEntity(IEngine engine, string modelAsset)
			: base(engine, modelAsset)
		{
			this.modelAsset = modelAsset;
			this.Forward = Vector3.Forward;
			this.Right = Vector3.Right;
			this.Up = Vector3.Up;
			//var gamePadService = engine.GetService<GamePadInputService>();
			//Services.Add(gamePadService);

			//gamePadService.Subscribe(this);
		}

		public override void Update(GameTime gameTime)
		{
			World = Matrix.CreateTranslation(this.Position);
		}

		public override void Render(GameTime gameTime)
		{
			var camera = cameraService.GetActiveCamera();

			Matrix[] transforms = new Matrix[Model.Bones.Count];
			Model.CopyAbsoluteBoneTransformsTo(transforms);

			foreach (ModelMesh mesh in Model.Meshes)
			{
				foreach (BasicEffect eff in mesh.Effects)
				{
					eff.EnableDefaultLighting();
					eff.World = transforms[mesh.ParentBone.Index] * World;

					eff.View = camera.View;
					eff.Projection = camera.Projection;
				}
				mesh.Draw();
			}
		}

		public override void LoadContent()
		{
			Model = ContentManager.Load<Model>(modelAsset);

			var root = (List<object>)Model.Tag;
			var r = root.First();
			int a = 0;
		}

		private float yaw, pitch, roll;
		private float yawSpeed = 0.1f;
		private float pitchSpeed = 0.1f;
		private float rollSpeed = 0.1f;
		private float velocity = 10f; // units per millisecond
		public void HandleInput(GameTime gameTime, GamePadState currentState, GamePadState previousState)
		{
			if (currentState.Buttons.A == ButtonState.Released &&
				previousState.Buttons.A == ButtonState.Pressed)
				this.IsAlive = false;

			float dt = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
			float lx = currentState.ThumbSticks.Left.X;
			float ly = currentState.ThumbSticks.Left.Y;
			float rx = -currentState.ThumbSticks.Right.X;
			float ry = currentState.ThumbSticks.Right.Y;
			float lt = currentState.Triggers.Left;
			float rt = currentState.Triggers.Right;

			yaw = rx * yawSpeed * dt;
			pitch = ry * pitchSpeed * dt;
			roll = lt * -rollSpeed * dt + rt * rollSpeed * dt;

			Matrix yawMat = Matrix.CreateFromAxisAngle(Vector3.Up, MathHelper.ToRadians(yaw));
			Matrix pitchMat = Matrix.CreateFromAxisAngle(Right, MathHelper.ToRadians(pitch));
			Matrix rollMat = Matrix.CreateFromAxisAngle(Forward, MathHelper.ToRadians(roll));

			var mat = yawMat * pitchMat * rollMat;

			Forward = Vector3.Normalize(Vector3.Transform(Forward, mat));
			Right = Vector3.Normalize(Vector3.Transform(Right, mat));
			Up = Vector3.Normalize(Vector3.Transform(Up, mat));

			Right = new Vector3(Right.X, 0.0f, Right.Z);
			Up = Vector3.Cross(Right, Forward);

			Vector3 oldPos = this.Position;
			this.Position = this.Position +
				this.Forward * ly * velocity * dt +
				this.Right * lx * velocity * dt;
			this.Velocity = (Position - oldPos) / dt;

			var world = Matrix.Identity;
			world.Up = Up;
			world.Right = Right;
			world.Forward = Forward;
			world.Translation = Position;
			this.World = world;
		}

		public FrogEngine.PlayerIndex PlayerIndex
		{
			get { return FrogEngine.PlayerIndex.One; }
		}
	}
}
